
import fs from "fs";
import path from "path";
import { StringConstant } from '../../utils/Constant'
import { contentRegExp } from '../../utils/RegExpUtils'
import { ComplieFileInfo, compileType, OutPutInfo } from '../../typedef/parseLog/parseLog'
import { applicationInfoMap, ApplicationInfo } from "../../utils/functionUtils";


export class compileFileInfo {

  /**
   * 遍历log文件内容，获取编译应用所需对比数据
   * 
   * @param oldCompile 
   * @param newCompile 
   * @returns 
   */
  static compileMap(oldCompile: Map<string, ComplieFileInfo>, newCompile: Map<string, ComplieFileInfo>): Array<OutPutInfo> {
    const outList: Array<OutPutInfo> = [];
    const arr: string[] = [...oldCompile.keys(), ...newCompile.keys()]
    const allKeys: string[] = [... new Set(arr)]

    for (const key of allKeys) {
      const out: OutPutInfo = new OutPutInfo();
      out.fileName = key;
      this.compileMapTime(oldCompile.get(key), newCompile.get(key), out, applicationInfoMap.get(key));
      this.compileMapAlarm(oldCompile.get(key), newCompile.get(key), out);

      outList.push(out);
    }

    return outList;
  }

  /**
   * 读文件内容，获取SDK编译应用耗时对比数据
   * 
   * @param oldComplieFileInfo 
   * @param newComplieFileInfo 
   * @param out 
   */
  static compileMapTime(oldComplieFileInfo: ComplieFileInfo | undefined, newComplieFileInfo: ComplieFileInfo | undefined, out: OutPutInfo, applicationInfo: ApplicationInfo | undefined): void {

    out.appType = applicationInfo?.appType || '';
    out.oldType = oldComplieFileInfo?.type || '';
    out.oldCompileArkTSTime = oldComplieFileInfo?.compileArkTSTime || '';
    out.oldSuccessfulTime = oldComplieFileInfo?.successfulTime || '';
    out.newType = newComplieFileInfo?.type || '';
    out.newCompileArkTSTime = newComplieFileInfo?.compileArkTSTime || '';
    out.newSuccessfulTime = newComplieFileInfo?.successfulTime || '';
    out.compileArkTSTimeDiff = timeDifference.timeComparison(out.oldCompileArkTSTime, out.newCompileArkTSTime);
    out.successfulTimeDiff = timeDifference.timeComparison(out.oldSuccessfulTime, out.newSuccessfulTime);

    // const newArkTSSecond: number = contentRegExp.secondNum(out.newCompileArkTSTime);
    // const newArkTSMillisecond: number = contentRegExp.millisecondNum(out.newCompileArkTSTime);
    // const newArkTSTimeStamps: number = timeDifference.timeStamp(newArkTSSecond, newArkTSMillisecond);
    // if (out.oldCompileArkTSTime && out.newCompileArkTSTime) {
    //   out.isCompileArkTSAlarm = (Math.abs(out.compileArkTSTimeDiff) * 100 / newArkTSTimeStamps).toFixed(2) + '%';
    // } else {
    //   out.isCompileArkTSAlarm = '100%'
    // }

    // const newSuccessSecond: number = contentRegExp.secondNum(out.newCompileArkTSTime);
    // const newSuccessMillisecond: number = contentRegExp.millisecondNum(out.newCompileArkTSTime);
    // const newSuccessTimeStamps: number = timeDifference.timeStamp(newSuccessSecond, newSuccessMillisecond);
    // if (out.oldSuccessfulTime && out.newSuccessfulTime) {
    //   out.isSuccessfulAlarm = (Math.abs(out.successfulTimeDiff) * 100/ newSuccessTimeStamps).toFixed(2) + '%';
    // } else {
    //   out.isSuccessfulAlarm = '100%'
    // }

    if (out.oldCompileArkTSTime && out.newCompileArkTSTime) {
      out.isCompileArkTSAlarm = Math.abs(out.compileArkTSTimeDiff) > StringConstant.ALARM_VALUE ? true : false;
    } else {
      out.isCompileArkTSAlarm = true
    }
    if (out.oldSuccessfulTime && out.newSuccessfulTime) {
      out.isSuccessfulAlarm = Math.abs(out.successfulTimeDiff) > StringConstant.ALARM_VALUE ? true : false;
    } else {
      out.isSuccessfulAlarm = true
    }
  }

  /**
   * 读文件内容，获取SDK编译应用告警差异对比数据
   * 
   * @param oldComplieFileInfo 
   * @param newComplieFileInfo 
   * @param out 
   */
  static compileMapAlarm(oldComplieFileInfo: ComplieFileInfo | undefined, newComplieFileInfo: ComplieFileInfo | undefined, out: OutPutInfo): void {
    const alarmSame: string[] = oldComplieFileInfo?.log.filter(ele => newComplieFileInfo?.log.includes(ele)) || [];
    const newAdded: string[] = newComplieFileInfo?.log.filter(ele => !alarmSame?.includes(ele)) || [];
    const oldDelete: string[] = oldComplieFileInfo?.log.filter(ele => !alarmSame?.includes(ele)) || [];
    //过滤is duplicate with
    this.setDuplicateMap(newAdded);
    this.setDuplicateMap(oldDelete);
    out.newAlarmAdded = this.judgeDuplicateMap(newAdded).join('； \n\n ')
    out.deleteAlarm =  this.judgeDuplicateMap(oldDelete).join('； \n\n ')
  }
  
  /**
   * 判断重复component id的正则
   *
   * @static
   * @memberof compileFileInfo
   */
  static duplicatePattern = /File:\s+(.+:\d+:\d+)\n.*component id \"(.*)\" is duplicate with(.+:\d+:\d+)/;

  /**
   * 根据收集的component id，判断新旧版本的是否需要替换
   *
   * @static
   * @param {string[]} stringArr
   * @return {*}  {string[]}
   * @memberof compileFileInfo
   */
  static judgeDuplicateMap(stringArr: string[]): string[] {
    return stringArr.filter(str => {
      const match = str.match(this.duplicatePattern);
      if (!match) {
        return true
      }
      const filePathFrom = match[1];  // 提取文件路径
      const component = match[2]; // 提取重复组件
      const filePathTo = match[3];  // 提取文件路径
      return !(duplicateMap.has(filePathFrom) && duplicateMap.get(filePathFrom) === component ||
        duplicateMap.has(filePathTo) && duplicateMap.get(filePathTo) === component);
    })
  }

  /**
   * 收集重复的component id，以文件行列信息为key，componentId为value
   *
   * @param {string[]} stringArr
   */
  static setDuplicateMap(stringArr: string[]): void {
    stringArr.forEach((item: string) => {
      const match = item.match(this.duplicatePattern);
      if (!match) {
        return
      }
      const filePathFrom = match[1];  // 提取文件路径
      const component = match[2]; // 提取重复组件
      const filePathTo = match[3];  // 提取文件路径
      duplicateMap.set(filePathFrom, component);
      duplicateMap.set(filePathTo, component);
    })
  }
  /**
   * 返回所有文件编译数据
   *
   * @param fileList 文件列表
   * @returns
   */
  static compileFileContent(fileList: Array<string>): Map<string, ComplieFileInfo> {
    const map: Map<string, ComplieFileInfo> = new Map();

    fileList.forEach((file: string) => {
      const dirName: string = path.basename(path.dirname(file));
      const fileName: string = path.basename(file, StringConstant.LOG);
      const fileContent: string = fs.readFileSync(file, StringConstant.UTF8);
      const alarm: string[] = contentRegExp.alarmContent(fileContent)


      const currentFileComplieInfo: ComplieFileInfo = new ComplieFileInfo(fileName, alarm);

      if (dirName.indexOf("compile-success-log") != -1) {
        currentFileComplieInfo.setType(compileType.SUCCESS);
        currentFileComplieInfo.setCompileArkTSTime(contentRegExp.compileArkTSTime(fileContent))
        currentFileComplieInfo.setSuccessfulTime(contentRegExp.successfulTime(fileContent))
      } else if (dirName.indexOf("compile-error-log") != -1) {
        currentFileComplieInfo.setType(compileType.ERROR);
      }

      map.set(fileName, currentFileComplieInfo);


    });

    return map;
  }
}

/**
 * 存储重复的component id 
 */
const duplicateMap: Map<string, string> = new Map();

export class timeDifference {

  /**
   * 获取时间差
   * 
   * @param oldTime 
   * @param newTime 
   * @returns 
   */
  static timeComparison(oldTime: string, newTime: string): number {
    const oldSecond: number = contentRegExp.secondNum(oldTime);
    const oldMillisecond: number = contentRegExp.millisecondNum(oldTime);
    const oldTimeStamps: number = timeDifference.timeStamp(oldSecond, oldMillisecond);

    const newSecond: number = contentRegExp.secondNum(newTime);
    const newMillisecond: number = contentRegExp.millisecondNum(newTime);
    const newTimeStamps: number = timeDifference.timeStamp(newSecond, newMillisecond);

    const timeComparisons: number = newTimeStamps - oldTimeStamps;

    return timeComparisons;
  }

  /**
   * 根据传入秒和毫秒，返回对应的毫秒数
   * 
   * @param seconds 秒数
   * @param milliseconds 毫秒数
   * @returns 
   */
  static timeStamp(seconds: number, milliseconds: number): number {
    const time: number = seconds * 1000 + milliseconds;

    return time;
  }
}